<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport"
			content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<title>实验室仪器检验</title>
		<!-- 页面样式 -->
		<link rel="stylesheet" href="./assets/css/QMS/PageCss/DocumentsPage.css">
		<link rel="stylesheet" href="./assets/css/QMS/luckysheet/pluginsCss.css">
		<link rel="stylesheet" href="./assets/css/QMS/luckysheet/luckysheet.css">
		<link rel="stylesheet" href="./assets/css/QMS/luckysheet/plugins.css">
		<link rel="stylesheet" href="./assets/css/QMS/luckysheet/iconfont.css">
		<!-- <link rel="stylesheet" href="http://at.alicdn.com/t/c/font_4096975_i8f4jjygw.css"> -->
		<link rel="stylesheet" href="./assets/css/QMS/vant.min.css">
		<link rel="stylesheet" href="./assets/css/QMS/element.css">
		<script src="./assets/script/my-xmlhttprequest.js"></script>
		<script src="./assets/script/jquery.js"></script>
		<script src="./assets/script/vue.min.js"></script>
		<script src="./assets/script/vant.min.js"></script>
		<script src="./assets/script/element.js"></script>
		<script src="./assets/script/plugin.js"></script>
		<script src="./assets/script/umd.js"></script>
		<script src="./assets/js/base.js"></script>
		<script src="./assets/js/luckysheetConfigByLab.js"></script>
		<script src="./assets/js/basicConfigByLab.js"></script>
		<!-- 检验报告测试用 -->
		<!-- <script src="./ReportPage/assets/js/morkData.js"></script> -->
	</head>
	<body>
		<div id="app" v-cloak style="display: flex;justify-content: space-between;">
			<div style="position: relative;flex: 1;">

				<van-nav-bar title="实验室检验" right-text="按钮" left-arrow @click-left="onClickLeft">
					<div slot="right" class="NavbarRight">
						<van-button v-if="WorkInstructions.length" size="mini" type="primary" plain
							@click="OpenInstruction = true" style="margin-right: 8px;">作业指导书</van-button>

						<van-switch v-model="isProductPriority" size="18" style="margin-right: 5px;"></van-switch>
						{{isProductPriority?'横向':'纵向'}}

						<div style="margin-left: 6px;">
							<el-dropdown trigger="click">
								<div style="display: flex;align-items: center;">
									<van-icon name="apps-o" size="26" color="#333"></van-icon>
								</div>

								<el-dropdown-menu slot="dropdown">
									<el-dropdown-item>
										<div @click="OpenMainBox">
											<span>单据信息</span>
										</div>
									</el-dropdown-item>
									<el-dropdown-item>
										<div @click="OpenControl">
											<span>切换设备</span>
										</div>
									</el-dropdown-item>
								</el-dropdown-menu>
							</el-dropdown>
						</div>
					</div>
				</van-nav-bar>

				<!-- luckysheet容器 -->
				<div id="luckysheet"></div>

				<!-- 底部Bottom -->
				<div class="bottom">
					<div class="buttonBox" :style="{'z-index' : !showEditWindow ? 999 : 9} ">
						<div class="BottomLeft">

							<!-- 连接状态 -->
							<div class="StatusBox" v-if="DeviceInfo.ShowDeviceType" @click="SendMessage('message')">
								<div class="deviceStatus"
									:style="{'background-color': deviceStatus ? '#17d56b':'#999'}">
								</div>
								<span class="StatusText"
									:style="{'color': deviceStatus ? '#17d56b':'#999'}">{{ deviceStatus ? '已连接' : '未连接' }}</span>
							</div>

							<div class="LeftTextBox">
								<div>
									<div>
										<span>样品数:</span>
										<span>{{originData.inspections.length}}</span>
									</div>

									<div>

										<span
											:style="{color: originData.mainData.Result == '1' ? '#17d56b':'#999'}">合格率:</span>
										<!-- <span
											:style="{color: originData.mainData.Result == '1' ? '#17d56b':'#999'}">{{QualifiedRate}}</span> -->
									</div>
								</div>
							</div>

							<div style="margin-left: 16px;font-size: 12px;color: #999;">
								<div>
									<span>所需设备：{{DeviceInfo.NeedDevice}}</span>
								</div>
							</div>

						</div>

						<div class="btnBox">
							<van-button
								v-if="ChoiceCellData.hasOwnProperty('IsLaboratory') && ChoiceCellData.IsLaboratory"
								type="info" style="margin-right: 10px;" @click="SendReportBtn">接收报告</van-button>



							<van-button v-if="originData.mainData.ApproveID != 1 && ApproveBack('提交')" @click="saveRow"
								type="info">提交</van-button>


						</div>
					</div>

					<div class="searchBox" ref="editKeyControl" :style="{zIndex : showEditWindow ? 999 : 9}"
						style="display: flex;align-items: center;justify-content: space-between;">
						<input :inputmode="InputFocus" type="text" class="IptStyle" id="autoInput" @blur="BlurSearch"
							@keydown.enter.prevent="submitKeyword"></input>

						<van-button class="confirmBtn" type="primary" size="small"
							@click="submitKeyword">确定</van-button>
					</div>

				</div>


				<!-- 主表弹窗 -->
				<van-popup v-model="showMainBox" position="left" :lock-scroll="false" round
					:style="{ height: '100%',width:'50%' }">
					<div class="FormBox">
						<van-form>
							<van-field readonly v-model="originData.mainData.BillNO" label="单据编号"></van-field>
							<van-field readonly v-model="originData.mainData.BillDate" label="单据日期"></van-field>
							<van-field readonly v-model="originData.mainData.LabTestPlanContent"
								label="检验任务"></van-field>
							<van-field readonly v-model="originData.mainData.ProductCode" label="品号"></van-field>
							<van-field readonly v-model="originData.mainData.ProductName" label="品名"></van-field>
							<van-field readonly v-model="originData.mainData.BJNum" label="样品数量"></van-field>
							<van-field readonly v-model="originData.mainData.CJNum" label="抽检数量"></van-field>
							<van-field readonly v-model="originData.mainData.AQL" label="抽样方案"></van-field>
							<van-field readonly v-model="originData.mainData.ReceiveNum" label="接收数量"></van-field>
							<van-field readonly v-model="originData.mainData.RejectionNum" label="拒收数量"></van-field>
							<!-- <van-field readonly v-model="originData.mainData.HGNumber" label="合格数量"></van-field>
							<van-field readonly v-model="originData.mainData.BHGNumber" label="不合格数量"></van-field> -->
							<!-- <van-field readonly v-model="originData.mainData.Result1" label="检验结果"
								:is-link="Permissions.HasChangeResult" @click="ChangeResult"></van-field> -->
							<!-- <van-field readonly v-model="originData.mainData.SFJY" label="是否检验"></van-field> -->
							<!-- <van-field readonly v-model="originData.mainData.Approve" label="是否审核"></van-field> -->
						</van-form>
					</div>

				</van-popup>


				<!-- 主表修改检验结果弹层 -->
				<van-popup v-model="ChangeResultPopup" style="min-width: 280px;">
					<van-nav-bar left-text="检验结果"></van-nav-bar>

					<van-radio-group v-model="originData.mainData.Result">
						<van-cell-group>
							<van-cell v-for="item in ResuleOptions" :key="item.ID" :title="item.NAME" clickable
								@click="ChoiceMainResult(item)">
								<template #right-icon>
									<van-radio :name="String(item.ID)" />
								</template>
							</van-cell>
						</van-cell-group>
					</van-radio-group>
				</van-popup>

				<!-- 子表表格检验弹层 -->
				<van-popup v-model="showResult" @close="closeJYResult" style="min-width: 280px;">
					<van-nav-bar left-text="检验结果"></van-nav-bar>

					<van-radio-group v-model="isJYResult">
						<van-cell-group>
							<van-cell title="合格" clickable @click="showResult = false;isJYResult = '合格'">
								<template #right-icon>
									<van-radio name="合格" />
								</template>
							</van-cell>
							<van-cell title="不合格" clickable @click="showResult = false;isJYResult = '不合格'">
								<template #right-icon>
									<van-radio name="不合格" />
								</template>
							</van-cell>
							<van-cell title="待检验" clickable @click="showResult = false;isJYResult = '待检验'">
								<template #right-icon>
									<van-radio name="待检验" />
								</template>
							</van-cell>


						</van-cell-group>
					</van-radio-group>
				</van-popup>

				<!-- 检验标准项实测值取值 -->
				<van-popup v-model="showSelectCellResult" @close="closeSelectCellResult" style="min-width: 280px;">
					<van-nav-bar left-text="检验结果"></van-nav-bar>

					<van-radio-group v-model="isSelectCellResult">
						<van-cell-group>
							<van-cell title="ok" clickable @click="selectCellResult('ok')">
								<template #right-icon>
									<van-radio name="ok" />
								</template>
							</van-cell>
							<van-cell title="ng" clickable @click="selectCellResult('ng')">
								<template #right-icon>
									<van-radio name="ng" />
								</template>
							</van-cell>
						</van-cell-group>
					</van-radio-group>
				</van-popup>


				<!-- 作业指导书列表 -->
				<van-popup v-model="OpenInstruction" round :close-on-click-overlay="false"
					:style="{ height: '80%',width: '90%' }">
					<div style="display: flex;flex-direction: column;height: 100%;">
						<van-cell title="作业指导书">
							<template #default>
								<van-icon name="cross" size="20" @click="OpenInstruction = false"></van-icon>
							</template>
						</van-cell>
						<!-- SendMessage('showPopup') -->
						<el-table :data="WorkInstructions" border style="width: 100%" :height="MinNums"
							@cell-click="ChoiceInstruction">
							<el-table-column align="center" prop="FileName" label="文件">
							</el-table-column>
							<el-table-column align="center" prop="ProductName" label="产品名称">
							</el-table-column>
							<el-table-column align="center" prop="format" label="文件格式">
							</el-table-column>
						</el-table>
					</div>
				</van-popup>




				<!-- 指定设备开启的对应展示弹层 -->
				<!-- 接收报告数据 -->
				<!-- showTableData_Report_popup -->
				<van-popup v-model="showTableData_Report_popup" round :close-on-click-overlay="false">
					<div class="f-dc rowDevice" style="width: 300px;height: 60vh;">
						<van-nav-bar left-text="检验报告">
							<template #right>
								<van-icon name="cross" size="18" @click="showTableData_Report_popup = false;" />
							</template>
						</van-nav-bar>

						<div class="flex-auto">
							<van-radio-group v-model="tableData_Report_radio" @change="tableData_Report_change">
								<van-cell-group>
									<van-cell v-for="(item,index) in tableData_Report" :title="'报告 ' + (index + 1)"
										clickable @click="tableData_Report_radio = index">
										<template #right-icon>
											<van-radio :name="index" />
										</template>
									</van-cell>
								</van-cell-group>
							</van-radio-group>

						</div>

						<div class="x-ec" style="padding: 10px;">
							<van-button style="margin-left: 6px;width: 80px;" size="small" type="info" plain
								@click="ViewReportInfoBtn">预览</van-button>
							<!-- <van-button style="margin-left: 6px;width: 80px;" size="small" type="info"
								@click="SubmitViewReportInfoBtn">确定</van-button> -->
						</div>

					</div>
				</van-popup>

				<!-- 检验报告 弹层 -->
				<van-popup v-model="showRowInfoByDevice" :close-on-click-overlay="false">
					<div class="f-dc rowDevice reportBox"
						:style="{height: ChoiceCellData.hasOwnProperty('Benchmark') && !ChoiceCellData.Benchmark.includes('光谱仪') ? '80vh' : '100%'}">
						<van-nav-bar class="popup_nav" left-text="检验报告">
							<template #right>
								<van-icon name="cross" size="18" @click="showRowInfoByDevice = false;" />
							</template>
						</van-nav-bar>

						<!-- <div class="popup_result" style="padding: 10px 10px 0;">
							<el-form ref="rowDeviceForm" label-width="80px">
								<el-form-item label="检验结果">

									<el-radio-group v-model="rowDeviceForm.result">
										<el-radio :label="1">合格</el-radio>
										<el-radio :label="0">不合格</el-radio>
									</el-radio-group>
								</el-form-item>
							</el-form>
						</div> -->

						<div class="flex-auto"
							v-if="ChoiceCellData.hasOwnProperty('Benchmark') && ChoiceCellData.Benchmark.includes('光谱仪')">
							<van-row class="rowDeviceBox">
								<van-col span="8" v-for="key in Object.keys(popup_ReportData)">
									<el-input v-model="popup_ReportData[key]" readonly>
										<template slot="prepend">{{key}}</template>
									</el-input>
								</van-col>
							</van-row>
						</div>

						<div style="height: 100%;width: 100%;overflow: hidden;"
							v-if="ChoiceCellData.hasOwnProperty('Benchmark') && ChoiceCellData.Benchmark.includes('三坐标')">
							<iframe id="report_threeCoordinates" v-if="openPopupIframe"
								src="./ReportPage/Report_SZB.html" class="report_iframe1"
								style="height: 100%;width: 100%;" frameborder="0"></iframe>
						</div>

						<div style="height: 100%;width: 100%;overflow: hidden;"
							v-if="ChoiceCellData.hasOwnProperty('Benchmark') && ChoiceCellData.Benchmark.includes('影像测量仪')">
							<iframe v-if="openPopupIframe" src="./ReportPage/Report_YXY.html" class="report_iframe1"
								style="height: 100%;width: 100%;" frameborder="0"></iframe>
						</div>

						<div class="x-ec btnBox" style="padding: 10px 15px;">

							<van-button type="info" class="confirmBtn" size="small"
								@click="submitRowInfo">确认</van-button>
						</div>
					</div>
				</van-popup>

			</div>

			<div v-if="IsShowWorkPage" style="border: 1px solid #333;min-width: 40vw;">
				<!-- :src="`${APP.IPAgreement() + APP.serverIP()}/assets/preOffice/preview.html?src=https://emoji.raingad.com/file/1.pdf`" -->
				<iframe style="width: 100%;height: 100%;" src="./Instruction.html" frameborder="0"></iframe>
			</div>

		</div>
	</body>
	<!-- 调用 uniapp webview 的 api ，记得需要写在 body 标签下面 -->
	<script src="./assets/script/uni.webview.1.5.4.js"></script>

	<script>
		// 开启 h5 页面 与 vue主页面的 信息交互
		document.addEventListener('UniAppJSBridgeReady', function() {
			// uni.postMessage({
			// 	data: {
			// 		action: 'message'
			// 	}
			// });
		});



		let vm = new Vue({
			el: '#app',
			data: {
				Permissions: { // 权限
					HasChangeResult: false, // 是否有主表修改结果的权限
				},
				InputFocus: 'none', // 输入框是否可弹起键盘
				DeviceInfo: {
					Communication: '', // 协议类型
					DeviceModel: '', // 选中的设备名称  用处：点击单元格，使用测量工具测量，若与之不一致，则无法测量
					ShowDeviceType: false, // 是否显示左下角设备连接状态，
					NeedDevice: '', // 点击单元格，所对应需要的测量设备
				},
				UserInfo: {}, // 用户信息
				deviceStatus: false, // 记录设备蓝牙连接状态


				showTableData_Report_popup: false, // 接收报告数据弹层
				tableData_Report_radio: 0, // 默认选中报告
				tableData_Report: [], // 接收报告数据的数组
				showRowInfoByDevice: false, // 展示子表为报告类型时，展示的弹层
				popup_ReportData: {}, // 报告类型弹层数据
				rowDeviceForm: { // 报告检验结果
					result: 1
				},
				report_frame_height: 0, // 报告弹层iframe高度
				openPopupIframe: false,

				ChoiceCellData: {}, // 单元格选中数据（允许修改的数据信息）

				MinNums: 250, // 单据列表表格高度
				showMainBox: false, // 是否显示主表内容弹层
				showResult: false, // 是否显示子表表格检验弹层
				isJYResult: '待检验', // 子表弹窗选中值（其实应该是 合格、不合格）
				isSelectCellResult: null, // 检验标准使用的弹层 ok、ng
				showSelectCellResult: false, // 检验标准实测值取值弹层
				immersed: 0, // 安全高度 
				IsWhere: 'A1', // 选中的单元格位置，默认选中 A1
				showEditWindow: false, // 是否显示输入框（只有双击可编辑的单元格的时候，才会为 true）
				allowToNext: false, // 允许跳转到下一个
				editKeyword: '', // 输入框值 
				editRange: [], // 单元格选中信息
				headerLevel: 0, // 标题头递归层级
				isProductPriority: false, // 横向、纵向
				RejectionNum: 0, // 根据来料数量返回的拒收数量（可以是不合格的数量）
				ChangeResultPopup: false, // 修改检验结果弹层
				// ChangeResult: '', // 检验结果弹层选中
				ResuleOptions: [], // 主表检验结果列表
				originData: {
					mainData: {}, // 主表数据
					inspections: [], // 子表数据
					FQCDetail: [] // 子子表数据
				},
				QualifiedRate: null, // 合格率
				editCells: [],
				OpenInstruction: false, // 是否显示作业指导书弹窗
				throttledOpen: false, // 打开作业指导书的节流记录，避免重复点击
				WorkInstructions: [], // 作业指导书
				RemarkIndex: { // 备注的索引位置
					r: null,
					c: null
				},
				IsShowWorkPage: false, // 是否展示作业指导书内容
				FilePath: null, // 作业指导书显示内容

				InspectionConfig: {
					keyID: "LabTestProductID", // 主键ID
					keyDeID: "LabTestProductDeID", // 子键ID
					keyDeDeID: "LabTestProductDeDeID", // 子子表ID
				},
				initConfigParam: {
					LabTestProductID: null,
					LabTestProductDeID: null,
					selectTimes: null,
					Times: null, // 检验次数
				},
				openSelectTimesPopup: false,

				BtnApprove: [], // 按钮权限数据
			},
			created: function() {
				var that = this;
				let immersed = 0;
				//获取当前手机状态栏高度
				if (window.localStorage.getItem('safeAreaInsetTop')) {
					immersed = window.localStorage.getItem('safeAreaInsetTop');
				} else {
					let ms = (/Html5Plus\/.+\s\(.*(Immersed\/(\d+\.?\d*).*)\)/gi).exec(navigator
						.userAgent);
					if (ms && ms.length >= 3) { // 当前环境为沉浸式状态栏模式
						immersed = parseFloat(ms[2]); // 获取状态栏的高度
					}
					window.localStorage.setItem('safeAreaInsetTop', immersed)

				}
				this.immersed = immersed;


				// 初始化时，取屏幕宽高的最小值，用于表格列表高度
				const MinNums = Math.min(screen.height, screen.width)
				let SetTableNums = 250

				if (MinNums < 500) {
					SetTableNums = 200
				} else {
					SetTableNums = 250
				}
				this.MinNums = SetTableNums

				setTimeout(() => {
					$('#app').css({
						'padding-top': immersed + 'px'
					})
				}, 50)
			},
			computed: {},
			watch: {
				QualifiedRate: {
					handler(val) { // 监听合格率，给主表赋值
						var that = this

						if (val == '100%') {
							that.originData.mainData.Result1 = that.FormatResultData(1);
							// that.originData.mainData.Result1 = '合格'
							that.originData.mainData.Result = "1"

						} else {

							let TrueLength = that.originData.inspections.filter(item => {
								return item.result != 1
							}).length;

							if (TrueLength >= that.RejectionNum) {
								that.originData.mainData.Result1 = that.FormatResultData(0);
								// that.originData.mainData.Result1 = '不合格'
								that.originData.mainData.Result = "0"
							} else {
								// that.originData.mainData.Result1 = '合格'
								that.originData.mainData.Result1 = that.FormatResultData(1);
								that.originData.mainData.Result = "1"
							}

						}
					},
					deep: true,
					// immediate: true
				},
				showRowInfoByDevice(nval) {
					if (nval == false) {
						vm.openPopupIframe = false;
					}
				}

			},
			mounted() {
				var that = this;
				that.$nextTick(() => {
					// 点击屏幕任何地方，都触发
					$(document).on('click', function(e) {
						console.log(!that.showEditWindow);
						if (!that.showEditWindow) {
							const input = document.getElementById('autoInput');
							input.focus(); // 初始聚焦

							input.addEventListener('blur', () => {
								setTimeout(() => input.focus(), 0); // 失焦后立即重新聚焦
							});

						}
					});


					// 在组件挂载后初始化Luckysheet
					// setTimeout(() => {
					$('#luckysheet').css({
						'height': `calc( 100vh - ${that.immersed}px - ${$('.van-nav-bar').height()}px - ${$('.bottom').height()}px - 4px ) `
					});
					// }, 300);
				})


				// 监听来自iframe的消息
				window.addEventListener('message', function(event) {
					// 如果iframe请求了父页面的数据，可以在这里回复
					if (event.data === 'getHeight') {
						let obj = {
							name: "getHeight",
							value: vm.report_frame_height
						}
						event.source.postMessage(obj, "*");
					} else if (event.data === 'getReportRadio') { // 选中报告索引
						let obj = {
							name: "getReportRadio",
							value: vm.tableData_Report_radio,
							typeName: vm.originData.FQCDetail[0].ItemName
						}
						event.source.postMessage(obj, "*");

					} else if (event.data === 'childData') { // 接收发送给报告页面的指令，获取数据

					}
				});

			},
			methods: {
				// 数据映射
				FormatResultData(ID) { // 根据结果ID，返回对应的结果名称
					let HasResult = vm.ResuleOptions.find(item => item.ID == ID)

					if (APP.isEmpty(HasResult)) {
						return ''
					} else {
						return HasResult['NAME']
					}
				},

				// 获取基础数据源
				GetMainResultList() { // 获取主表检验结果列表
					APP.jqueryAjax('APP_JHJYD_PDJG', {}, function(res) {
						if (res) {
							if (res.status == 200) {
								vm.ResuleOptions = res.data.ds
							}

						}
					})
				},



				// 初始化



				ChoiceTableCell(row, column, cell, event) { // 单击表格行
					// 记录点击的表格行ID，同时用于弹窗表格右上方按钮，有值时显示 关闭弹窗，无时显示 退出
					vm[vm.InspectionConfig.keyID] = row[vm.InspectionConfig.keyID];
					// 获取 APP进货检验单明细
					APP.jqueryAjax('Qu_LabTestTaskDetails', row, function(res) {

						if (res.status == 200) {
							const {
								ds,
								ds1,
								ds2,
								ds3,
								ds4
							} = res.data;
						}

						// return
						// 计算合格率
						// vm.QualifiedRate = BackRercentageData(res.data.ds1, 'FResult', 1)

						Promise.resolve().then(async () => {
							// 给主表赋值
							let mainData = res.data.ds[0];
							// 因为主表的结果下拉，需要字符串格式
							if (mainData.Result != null && mainData.Result != undefined) {
								mainData.Result = String(mainData.Result)
							}
							mainData["Times"] = vm.initConfigParam.selectTimes;
							vm.originData.mainData = mainData;

							let basicConfigInfo = await basicConfig.initConfig(res.data,
								"LabTestProductYPDeID",
								"LabTestProductYPDeID");


							Object.assign(vm.originData, {
								inspections: basicConfigInfo.inspections,
								FQCDetail: basicConfigInfo.FQCDetail,
							});


							// 对获取数据后 重构的对象数据，进一步重构
							// vm.getPageData();
							basicConfig.initPageStr()

							// vm.GetFileType(vm.originData.mainData.ProductID); // 根据产品ID，获取作业指导书数据
						})


					})
				},




				saveRow() { // 提交按钮
					let that = this;
					vant.Toast.loading({
						message: '加载中...',
						forbidClick: true,
					});

					const {
						mainData,
						inspections,
						FQCDetail
					} = this.originData;

					// 使用 flatMap 一步展开 basicData
					const basicData = inspections.flatMap((item) => item.FQCItems);

					// 使用 Map 加速匹配操作
					const itemMap = new Map();

					for (const row of basicData) {
						const key = row.LabTestProductItemDeID;
						if (!itemMap.has(key)) {
							itemMap.set(key, []);
						}
						itemMap.get(key).push(row);
					}


					const filterData = FQCDetail.filter((item) => item.Type != 0).map((item) => ({
						...item,
						nood: itemMap.get(item.ItemID) || [],
					}));

					let saveData = {
						mainData: {
							...mainData,
							Times: 1,
						},
						rowData: filterData
					}


					const obj = {
						json: JSON.stringify(saveData)
					};

					vant.Toast.loading({
						message: '准备提交...',
						forbidClick: true,
					});
					APP.jqueryAjax('updateLibIns', obj, (res) => {
						if (res.status == 200) {
							vant.Toast.success({
								message: '提交成功',
								forbidClick: true,
							});

							// 通知实验室明细刷新

							that.SendMessage('refreshPage');

							setTimeout(() => {
								vant.Toast.clear();
							}, 1000);
						} else {

							vant.Toast.fail('提交失败，请重新提交')

						}
					}, (err) => {
						vant.Toast.clear();
						vant.Toast('提交失败，请重新提交或联系工作人员')
					}, '1')

				},

				// 通用，可覆盖
				GetFileType(ID) { // 根据产品ID，获取作业指导书数据
					var that = this;
					that.WorkInstructions = []
					try {
						APP.jqueryAjax('selectSIPByProductID', {
							ProductID: ID
						}, function(res) {
							if (res.status == 200) {
								if (res.data.ds && res.data.ds.length) {
									res.data.ds.map(item => {
										item.format = that.getExtensionAfterLastDot(item.FilePath)
									})
									that.WorkInstructions = res.data.ds
								}

							}
						})
					} catch (e) {
						//TODO handle the exception
					}
				},
				getExtensionAfterLastDot(str) { // 根据传入地址，返回文件流格式类型：pdf excel
					const lastDotIndex = str ? str.lastIndexOf('.') : -1;
					return lastDotIndex !== -1 ? str.substring(lastDotIndex + 1) : '';
				},
				ChoiceInstruction(row) { // 选中作业指导书
					var that = this;
					if (!row.FilePath) {
						return vant.Toast.fail("无法找到链接");
					}
					this.FilePath = row.FilePath;
					this.OpenInstruction = false;
					// this.IsShowWorkPage = true;

					// vm.getPageData();
					// return

					if (!that.throttledOpen) {
						that.throttledOpen = true;
						let param = {
							url: row.FilePath,
							title: row.FileName,
						}
						that.SendMessage('showPopup', param);
						setTimeout(() => { // 做一下节流操作
							that.throttledOpen = false;
						}, 3000)
					}
				},

				// 向外部通讯
				SendMessage(Text, data) { // 向外部发送

					let Obj = {
						action: Text,
						param: {
							url: '',
							title: '',
						},
					}

					if (Text == 'showPopup') { // 如果是作业指导书，将地址传出去
						Obj['param']['url'] = data.url;
						Obj['param']['title'] = data.title;
					} else if (Text == 'ToReviewPageInfo') { // 不合格评审
						Obj['param']['BadReviewID'] = data.BadReviewID;
					} else if (Text == 'baseScreen') { // 筛选下拉
						Obj['param'] = data
					} else if (Text == 'Laboratory') { // 实测报告类型，打开对应设备的弹层
						Obj['param'] = data
					}

					uni.postMessage({
						data: Obj
					});
				},
				// 外部调用内部方法
				GetBtnPermission(data) {
					this.BtnApprove = JSON.parse(data);
				},
				ApproveBack(str) {
					let that = this;
					let Type = that.BtnApprove.some(item => {
						return item.MenuName == str
					})

					return Type;
				},

				parseQueryString(queryString) {
					let vm = this;
					// 如果queryString不包含"?"，则默认整个字符串为URL部分  
					const [url, queryStringPart] = queryString.split('?');

					// 如果没有查询字符串部分，直接返回包含URL的结果  
					if (!queryStringPart) {
						return {
							Url: url.replace(/\.vue$/, '')
						};
					}

					let params = queryStringPart.split('&').reduce((acc, current) => {
						let [key, value] = current.split('=');
						acc[key] = value;
						return acc;
					}, {});

					params['Url'] = url.replace(/\.vue$/, '');;
					return params
				},


				page_initConfig(data) { // 初始化
					const {
						// GetDeviceStatus,
						GetUserInfo,
						SetServiceIP,
						GetBtnPermission
					} = JSON.parse(data);


					this.UserInfo = GetUserInfo;
					APP.getUserInfo(GetUserInfo);

					APP.serverIP(SetServiceIP.serverIP);
					APP.IPAgreement(SetServiceIP.IPAgreement);
					const {
						LabTestProductID,
						LabTestProductDeID,
						MeasureTypeID
					} = this.parseQueryString(window.location.search);

					Object.assign(this.initConfigParam, {
						LabTestProductID: +LabTestProductID || 0,
						LabTestProductDeID: +LabTestProductDeID || 0,
						Times: 1,
						MeasureTypeID: MeasureTypeID
					});

					if (GetBtnPermission) {
						this.BtnApprove = GetBtnPermission;
					}

					this.ChoiceTableCell(this.initConfigParam);
					// 打开弹层，选择查看的检验次数数据
					// this.openSelectTimesPopup = true;
				},

				SetServiceIP(IP) { // 从外部获取账套IP地址
					var that = this
					let data = JSON.parse(IP);
					APP.serverIP(data.serverIP);
					APP.IPAgreement(data.IPAgreement);
					const {
						LabTestProductID,
						LabTestProductDeID,
						// Times
					} = this.parseQueryString(window.location.search);

					// that.ChoiceTableCell(row);


					// 	// 获取一下主表检验结果列表
					// 	vm.GetMainResultList()

					// 	// 获取是否有权限显示
					// 	vm.GetPermissions()
					// }, 500)
				},
				GetPermissions() { // 获取是否有权限显示
					APP.jqueryAjax('updateResult', {
						UserID: vm.UserInfo.UserID
					}, function(res) {
						if (res.status == 200) {
							vm.Permissions.HasChangeResult = Boolean(+res.data.ds[0].changeResult);
						}
					})
				},
				ChangeResult() { // 点击主表修改检验结果，打开弹层
					// 有权限才能修改检验结果
					if (vm.Permissions.HasChangeResult) {
						vm.ChangeResultPopup = true;
					}
				},
				GetUserInfo(data) { // 从外部获取获取用户信息
					var that = this;
					that.UserInfo = JSON.parse(data);
					// that.UserInfo = data;

					APP.getUserInfo(JSON.parse(data));
				},


				OpenMainBox() { // 打开主表弹窗
					vm.showMainBox = true
					// 给左侧主表弹窗 顶部 加 安全高度
					setTimeout(() => {
						$('.FormBox').css({
							'padding-top': vm.immersed + 'px'
						})
					}, 300)
				},
				ChoiceMainResult(data) { // 修改主表检验结果
					// 点击 cell 后 需要手动修改值，不然无法修改值
					vm.originData.mainData.Result = String(data.ID)
					vm.originData.mainData.Result1 = data.NAME

					vm.ChangeResultPopup = false
				},
				OpenControl() { // 切换设备
					this.SendMessage('openDeviceControl')
				},


				getPageData() {
					const that = this;
					const headerTitles = that.originData.FQCDetail;
					const headerLevel = that.getTreeDepth(headerTitles);
					that.headerLevel = headerLevel;

					const allCellData = [];
					const dataVerfications = {};
					that.editCells = [];

					// 工具函数：创建单元格
					const createCell = (r, c, value, color = '#333', bold = 0) => ({
						r,
						c,
						v: {
							v: value,
							m: value,
							ff: 1,
							fc: color,
							bl: bold,
							fs: 9,
							ht: 0,
							vt: 0,
							tb: 2
						}
					});

					// 第一列样品名称标题（合并单元格）
					allCellData.push({
						r: 0,
						c: 0,
						v: {
							v: '样品名称',
							m: '样品名称',
							ff: 1,
							fc: '#333',
							bl: 1,
							fs: 9,
							ht: 0,
							vt: 0,
							tb: 2,
							mc: {
								r: 0,
								c: 0,
								rs: headerLevel + 1,
								cs: 1
							}
						}
					});

					// 表头（已去掉上限、下限、检验标准）
					that.getTitleHeader(headerTitles, 0, 0, allCellData, 0);

					// 分组 + 统计列数（现在每个检验项都只占 1 列）
					const type1Details = [];
					const type2Details = [];
					const typeCounts = {
						1: 0,
						2: 0
					};

					for (const item of headerTitles) {
						if (item.Type === 1) {
							type1Details.push(item);
							typeCounts[1]++;
						} else if (item.Type === 2) {
							type2Details.push(item);
							typeCounts[2]++;
						}
					}

					const colNums = (typeCounts[1] * 1) + (typeCounts[2] * 1) + 1; // 每个检验项 1 列 + 样品名称列

					// 备注列位置
					that.RemarkIndex.c = colNums + 1;
					that.RemarkIndex.r = headerLevel;

					// 构建正反映射
					const fqcDetailType1 = type1Details;
					const fqcDetailType2 = type2Details;
					const reverseMap = {
						1: {},
						2: {}
					};

					const sampleFQCItems = that.originData.inspections[0]?.FQCItems || [];
					let t1Index = 0,
						t2Index = 0;
					for (const item of sampleFQCItems) {
						if (item.Type === 1 && fqcDetailType1[t1Index]) {
							reverseMap[1][fqcDetailType1[t1Index].ItemID] = item.FQCItemID;
							t1Index++;
						} else if (item.Type === 2 && fqcDetailType2[t2Index]) {
							reverseMap[2][fqcDetailType2[t2Index].ItemID] = item.FQCItemID;
							t2Index++;
						}
					}

					// 遍历样品
					for (let i = 0; i < that.originData.inspections.length; i++) {
						const rowIndex = headerLevel + 1 + i;
						const inspection = that.originData.inspections[i];

						// 样品名称
						allCellData.push(createCell(rowIndex, 0, inspection.name));

						// 构建当前样品的 Map（FQCItemID -> 对象）
						const inspectionItemMap = new Map();
						for (const fqc of inspection.FQCItems) {
							inspectionItemMap.set(fqc.FQCItemID, fqc);
						}

						// Type 1（只保留实测值）
						for (const item of type1Details) {
							const baseCol = item.c;
							const matchFQCItemID = reverseMap[1][item.ItemID];
							const actual = inspectionItemMap.get(matchFQCItemID);

							let actualVal = '';
							let color = "#333";

							if (actual) {
								actualVal = actual.value;
								// 如果需要颜色判断，保留，否则可以删掉
								if ($.isNumeric(actualVal)) {
									color = "#07d348"; // 默认绿，可按规则改
								}
								actual.r = rowIndex;
								actual.c = baseCol;
								that.editCells.push({
									...actual
								});
							}
							allCellData.push(createCell(rowIndex, baseCol, actualVal, color));
						}

						// Type 2（只保留实测值）
						for (const item of type2Details) {
							const baseCol = item.c;
							const matchFQCItemID = reverseMap[2][item.ItemID];
							const actual = inspectionItemMap.get(matchFQCItemID);

							let actualVal = '';
							let color = "#333";

							if (actual) {
								const val = (actual.value || '').toString().toLowerCase();
								if (val === 'ok') color = '#07d348';
								else if (val === 'ng') color = '#f00';
								else if (val === '') color = '#a8a8a8';

								actualVal = actual.value;
								actual.r = rowIndex;
								actual.c = baseCol;
								that.editCells.push({
									...actual
								});
							}
							allCellData.push(createCell(rowIndex, baseCol, actualVal, color));
						}
					}

					// 检验结果行
					const resultRowIndex = headerLevel + 1 + that.originData.inspections.length;
					allCellData.push(createCell(resultRowIndex, 0, '检验结果', '#333', 1));

					for (const item of headerTitles) {
						if (item.Type === 1 || item.Type === 2) {
							let resultText = '待检';
							let fontColor = '#a8a8a8';

							if (item.FResult === 1) {
								resultText = '合格';
								fontColor = '#07d348';
							} else if (item.FResult === 0) {
								resultText = '不合格';
								fontColor = '#f00';
							}
							allCellData.push(createCell(resultRowIndex, item.c, resultText, fontColor));
						}
					}

					// 渲染表格
					const rowNums = headerLevel + 1 + that.originData.inspections.length + 1;
					that.ExcleInit(rowNums, colNums, allCellData, dataVerfications);
				},

				/**
				 * 获取最大树层级数（根为第1层）
				 * @param {Array} list - 平铺结构的数组
				 * @param {Object} options - 字段名映射
				 * @param {string} options.idKey - 节点ID字段名
				 * @param {string} options.parentKey - 父节点字段名
				 * @returns {number} 最大层级数
				 */
				getTreeDepth(
					list, {
						idKey = 'ItemID',
						parentKey = 'UpID'
					} = {}
				) {
					const map = new Map();
					for (const item of list) {
						map.set(item[idKey], item);
					}

					const depthMap = new Map(); // 缓存每个节点的深度
					let maxDepth = 0;

					function getDepth(node) {
						const id = node[idKey];
						if (depthMap.has(id)) return depthMap.get(id);

						const parentId = node[parentKey];
						let depth;
						if (parentId === '' || parentId === null || !map.has(parentId)) {
							depth = 1;
						} else {
							const parent = map.get(parentId);
							depth = getDepth(parent) + 1;
						}

						depthMap.set(id, depth);
						return depth;
					}

					for (const node of list) {
						const d = getDepth(node);
						if (d > maxDepth) maxDepth = d;
					}

					return maxDepth;
				},
				getHeaderTitlesLevel(originData, parentID, originLevel) {
					var that = this;
					var maxLevel = originLevel;
					for (var i = 0; i < originData.length; i++) {
						if (originData[i].UpID == parentID) {
							var curLevel = that.getHeaderTitlesLevel(originData, originData[i].ItemID,
								originLevel +
								1);
							if (curLevel > maxLevel) {
								maxLevel = curLevel;
							}
						}
					}
					return maxLevel;
				},
				getTitleHeader(originData, parentID, originLevel, allCellData, originCNum) {
					const that = this;
					let cNum = originCNum;

					for (let i = 0; i < originData.length; i++) {
						const item = originData[i];
						if (item.UpID !== parentID) continue;

						if (item.Type === 0) {
							// 普通分组类
							const cSplitNum = that.getSplitNum(originData, item.ItemID);
							allCellData.push(createCell(originLevel, cNum + 1, cSplitNum, item.ItemName));
							that.getTitleHeader(originData, item.ItemID, originLevel + 1, allCellData, cNum);
							cNum += cSplitNum;
						} else {
							// 检验项（Type 1 / Type 2 都直接简化成 1 列：实测值）
							item.c = cNum + 1;
							item.cmax = cNum + 1;

							allCellData.push(createCell(originLevel, cNum + 1, 1, item.ItemName));
							allCellData.push(createCell(originLevel + 1, cNum + 1, 1, '实测值'));
							cNum += 1;
						}
					}

					// 生成单元格的内部方法
					function createCell(row, col, colSpan, value) {
						return {
							r: row,
							c: col,
							v: {
								ct: {
									fa: "General",
									t: "n"
								},
								v: value,
								m: value,
								ff: 1,
								fc: "#333",
								bl: 1,
								fs: 9,
								ht: 0,
								vt: 0,
								tb: 2,
								mc: {
									r: row,
									c: col,
									rs: 1,
									cs: colSpan
								}
							}
						};
					}
				},
				getSplitNum(originData, parentID) {
					var that = this;
					var splitNum = 0;
					for (var i = 0; i < originData.length; i++) {
						if (originData[i].UpID == parentID) {
							if (originData[i].Type == 0) {
								var subSplitNum = that.getSplitNum(originData, originData[i].ItemID);
								splitNum = splitNum + subSplitNum;
							} else if (originData[i].Type == 1) {
								splitNum = splitNum + 3;
							} else {
								splitNum = splitNum + 2;
							}
						}
					}
					return splitNum;
				},
				cellToIndex(cell) { // 单元格转换  将 A1 转换成 [0,0]
					return APP.excelAddressToArrayIndex(cell)
				},
				indexToCell(index) { // 将 [0,0] 转换成 A1  [26,0] => AA1
					const column = APP.createCellPos(index[1]); // 将列索引转换为列字母，0对应A，1对应B，以此类推
					const row = index[0] + 1; // 将行索引转换为行数字，加上1是因为单元格标识从1开始
					return column + row;
				},
				setRange(ret, str) { // 父组件调用子组件事件 - data => 父组件传入的值;
					console.log(str);
					console.log(JSON.stringify(vm.ChoiceCellData.IsLaboratory));
					if (!str && vm.ChoiceCellData.IsLaboratory) {
						return
					}


					let data = ''
					if (ret) {
						data = ret;
					};

					let dataArray = data.split(',');


					// IsWhere => A1 => [0,0]
					// 1、获取选中单元格行列位置
					const Iswhere = vm.cellToIndex(vm.IsWhere);

					let ranged = {
						r: Iswhere[0],
						c: Iswhere[1],
					};

					//考虑到data是由逗号分割的字符串
					if (dataArray.length > 1) {
						//1、某一行 有实测值1、实测值2、实测值3
						//2、点击其中一个实测值 赋值该行的所有实测值
						//获取点击行的行号
						let r = vm.cellToIndex(vm.IsWhere)[0];
						//获取该行的所有可填实测值
						let AllFilterData = [];
						vm.originData.inspections.forEach(item => {
							let FilterData = item.FQCItems.filter(ReItem => {
								return ReItem.r == ranged.r
							});
							if (FilterData.length) {
								AllFilterData.push(FilterData);
							};
						});
						//按行列大小排序
						AllFilterData[0].sort((a, b) => {
							return (a.c - b.c);
						});
						for (let i = 0; i < AllFilterData[0].length; i++) {
							vm.IsWhere = vm.indexToCell([AllFilterData[0][i].r, AllFilterData[0][i].c]);
							let NewData = [
								[{
									"m": dataArray[i], // 显示值
									"v": dataArray[i], // 原始值
									"ht": 0, // 水平对齐 0 居中、1 左、2右	
									"vt": 0, // 垂直对齐 0 中间、1 上、2下
									"tb": 2, // 文本换行 0 截断、1溢出、2 自动换行
								}]
							];
							//点击该行的任意一个单元格也会对该行的所有可填实测值赋值
							vm.ChoiceCell(NewData)
						}

					} else {
						const NewData = [
							[{
								"m": data, // 显示值
								"v": data, // 原始值
								"ht": 0, // 水平对齐 0 居中、1 左、2右	
								"vt": 0, // 垂直对齐 0 中间、1 上、2下
								"tb": 2, // 文本换行 0 截断、1溢出、2 自动换行
							}]
						];

						// 首先判断选中单元格是否需要所属检验工具测量

						// 判断当前项是否为报告类型
						if (vm.ChoiceCellData && vm.ChoiceCellData.hasOwnProperty("IsLaboratory") && vm.ChoiceCellData
							.IsLaboratory) {

							// 直接赋值
							vm.AssignmentFun(NewData, data);
						} else {
							// 外部数据传入--赋值--跳转下一个

							// 2、过滤出填报项列表中
							// 2.1、是否包含该位置单元格，
							// 2.2、如果包含，判断检验工具是否为连接设备
							let AllFilterData = [];
							vm.originData.inspections.forEach(item => {
								let FilterData = item.FQCItems.filter(ReItem => {
									return ReItem.r == ranged.r && ReItem.c == ranged.c
								});
								if (FilterData.length) {
									AllFilterData.push(FilterData);
								};
							});


							// 3、如果选中项属于填写数据，且填写设备 Benchmark 为连接设备，则进行赋值操作，并选择下一个，反之，提示错误
							if (AllFilterData.length) {
								vm.ChoiceCell(NewData)
							}
						}

					}

				},
				GetDeviceStatus(data) { // 获取设备连接状态
					vm.deviceStatus = JSON.parse(data);
				},
				/** 将字符中的中文句号转换为英文句号
				 * @param {Object} data
				 */
				NumberMapBack(data) {
					if (data) {
						return data.replace(/。/, '.', 1);
					}
					return '';
				},
				AssignmentFun(data, value) { // 赋值操作
					// vm.editKeyword = data[0][0]['v']
					$('#autoInput').val(data[0][0]['v'])
					// 修改界面上显示的数值
					luckysheet.setRangeValue(data, {
						range: vm.IsWhere + ':' + vm.IsWhere
					});
					// 拿到回传的单元格位置后，转换格式： A1 => [0,0]
					var CellWhere = vm.cellToIndex(vm.IsWhere)
					var TheIndex = null
					// 将单元格位置信息与数据进行匹配，替换所在单元格的value值
					vm.originData.inspections.forEach((item, index) => {
						item.FQCItems.forEach(ReItem => {
							if (ReItem.r == CellWhere[0] && ReItem.c == CellWhere[1]) {
								TheIndex = index;

								ReItem.value = value;

								// 如果该单元格数据是有 上下限, 1 => 合格, 2 => 不合格
								if (ReItem.minNum && ReItem.maxNum) {
									let keyValue = +vm.NumberMapBack($('#autoInput').val()) || 0;

									if (+ReItem.maxNum >= keyValue && keyValue >= +ReItem.minNum) {
										ReItem.result = 1
									} else {
										ReItem.result = 0
									}
								} else {

									if (ReItem.value.toLowerCase() === 'ok') {
										ReItem.result = 1
									} else if (ReItem.value.toLowerCase() === 'ng') {
										ReItem.result = 0;
									} else {
										ReItem.result = 99;
									}
								}
							}
						})
					});

					// 根据当前样品的result是否为true，改变检验结果
					vm.originData.inspections.forEach((item, index) => {
						if (TheIndex == index) {
							let HasNotResult = item.FQCItems.some(ReItem => {
								return ReItem.result == 2
							})
							if (HasNotResult) {
								item.result = 2
							} else {
								item.result = 1
							}
						}
					})


					// 更改行的检验结果
					vm.ChangeRowResult(CellWhere[0], TheIndex)


				},
				ChangeRowResult(ranged1) { // 更改行的检验结果
					let ranged = {
						r: vm.editRange[0].row_focus,
						c: vm.editRange[0].column_focus,
					}

					// 清空输入框中的数据
					$('#autoInput').val('');

					function checkColumnResult(dataList, columnIndex) {
						// 收集该列所有项
						const columnItems = dataList
							.flatMap(sample => sample.FQCItems)
							.filter(item => item.c === columnIndex);

						// 无此列
						if (columnItems.length === 0) {
							return {
								isFinished: false,
								result: 99
							};
						}

						// 是否所有值都已填写
						const isFinished = columnItems.every(item => (item.value || '').trim() !== '');
						if (!isFinished) {
							return {
								isFinished: false,
								result: 99
							};
						}

						// 统计不合格项数量
						const failCount = columnItems.filter(item => item.result === 0).length;

						// 判断最终结果
						let finalResult = 99; // 默认待检验

						if (failCount > 0) {
							finalResult = failCount <= vm.originData.mainData.RejectionNum ? 1 : 0; // 可接受则合格，否则不合格
						} else {
							finalResult = 1; // 全部合格
						}

						return {
							isFinished: true,
							result: finalResult
						};
					}

					const {
						isFinished,
						result
					} = checkColumnResult(vm.originData.inspections, ranged.c);


					let resRange = {
						r: vm.headerLevel + vm.originData.inspections.length + 1,
						c: ranged.c
					};


					let restleText = isFinished ? (result == 1 ? '合格' : result == 0 ? '不合格' : '待检验') : '待检验';
					let restleTextColor = result == 1 ? "#07d348" : result == 0 ? "#f00" : "#a8a8a8"

					const NewData = [
						[{
							"m": restleText, // 显示值
							"v": restleText, // 原始值
							"ht": 1, // 水平对齐 0 居中、1 左、2右	
							"vt": 0, // 垂直对齐 0 中间、1 上、2下
							"tb": 2, // 文本换行 0 截断、1溢出、2 自动换行 
							"fc": restleTextColor
						}]
					]

					// 获取检验结果列
					// var MaxColumn = countMax(vm.originData.inspections[TheIndex].FQCItems, 'c')

					//回写单元格
					var IsWhere = vm.indexToCell([resRange.r, resRange.c])

					luckysheet.setRangeValue(NewData, {
						range: IsWhere + ':' + IsWhere
					});

					// 计算合格率
					// vm.QualifiedRate = BackRercentageData(vm.originData.inspections, 'result', 1)

					if (isFinished) {
						// 检验完毕后，赋值检验结果给检验项
						for (let i = 0; i < vm.originData.FQCDetail.length; i++) {
							if (vm.originData.FQCDetail[i].cmax == ranged.c) {
								vm.originData.FQCDetail[i]['result'] = result;
								break;
							}

						}

						luckysheet.setDataVerification({
							type: 'checkbox',
							type2: null,
							value1: '合格',
							value2: '不合格',
							checked: result == 1 ? true : false
						}, {
							range: IsWhere
						});
					}
				},
				ChoiceCell(data) { // 赋值完选择下一个
					// 赋值
					vm.AssignmentFun(data, data[0][0]['v'])

					/**
					 *  AllFQCItems 			符合检验设备的总数组  
					 *  CellWhere 			选中项单元格所在位置  
					 *  vm.isProductPriority  横纵向， 横向 true，纵向 false
					 */
					// 获取选中位置 将 A1 类型转化为 [0,0]
					let CellWhere = vm.cellToIndex(vm.IsWhere)
					let AllFQCItems = [] // 接收一个总的数组，按顺序操作
					// 如果是横向赋值
					if (vm.isProductPriority) {
						// 横向 => 按样品顺序push
						vm.originData.inspections.forEach((item) => {
							// AllFQCItems.push(...item.FQCItems)
							let Arr = []
							item.FQCItems.forEach(ReItem => {
								Arr.push(ReItem)
							})
							AllFQCItems.push(...Arr)

						})

					} else {
						// 纵向 => 按 将每一个样品从头到尾的顺序，一起push
						let AllArr = []
						vm.originData.inspections.forEach((item, index) => {

							let Arr = []
							item.FQCItems.forEach(ReItem => {
								Arr.push(ReItem)
							})
							AllArr.push(Arr)
						})

						let List = []
						if (AllArr.length) {
							for (let i = 0; i < AllArr[0].length; i++) {

								for (let j = 0; j < AllArr.length; j++) {
									AllFQCItems.push(AllArr[j][i])

								}
							}
						}
					}


					let r = CellWhere[0]
					let c = CellWhere[1]

					let RIndex = 0 // 行
					let CIndex = 0 // 列

					let TheIndex = 0
					AllFQCItems.forEach((item, index) => {
						if (item.r == r && item.c == c) {
							TheIndex = index
						}
					})
					// 从符合条件的数组中，过滤掉 被赋值项本身及之前的数据；用filter是为了防止原数组被修改
					let NewAllFQCItems = AllFQCItems.filter((item, index) => {
						return index > TheIndex
					})
					// 过滤完后，还有数据，则跳下一个；反之弹出提醒，可录入完毕
					if (NewAllFQCItems.length) {
						// 选中
						let IsWhere = vm.indexToCell([NewAllFQCItems[0].r, NewAllFQCItems[0].c])
						luckysheet.setRangeShow(IsWhere + ':' + IsWhere);
						vm.IsWhere = IsWhere
						// 输入框聚焦
						// 聚焦必须要时间，否则无法聚焦
						setTimeout(function() {
							vm.$refs.editKeyControl.querySelector('input')
								.focus();
							$('#autoInput').val('')
						}, 50);
					} else {
						$('#autoInput').val('');
						vm.showEditWindow = false;
						vm.allowToNext = false;
					}

				},
				GoBack() {
					setTimeout(() => {
						// uni.navigateBack()
						let Obj = {
							action: 'GoBack',
							param: {
								url: '',
								title: '',
							},
						};

						uni.postMessage({
							data: Obj
						});
					}, 30)
				},
				ExcleInit(rowNums, colNums, cellData, dataVerfications) {
					var that = this;
					var options = {
						container: 'luckysheet', //luckysheet is the container id
						title: 'Luckysheet Demo', // 设定表格名称
						lang: 'zh', // 设定表格语言
						showtoolbar: false,
						showinfobar: false,
						showsheetbar: false,
						sheetFormulaBar: false,
						showstatisticBar: true, // 缩放按钮
						showcolumnbar: false,
						enableAddRow: false,
						enableAddBackTop: false,
						keyboardenable: false, // 禁止键盘弹起选中单元格
						editable: false, // 设置为只读模式
						rowHeaderWidth: 0,
						columnHeaderHeight: 0,
						rowTitleCellRenderAfter: false,
						columnTitleCellRenderAfter: false,
						data: luckysheetConfig.getOptionsData(rowNums, colNums, cellData, dataVerfications),
						hook: {
							rangeSelect(sheet, range) { // 框选或者设置选区后触发,(点击单元格)
								luckysheetConfig.rangeSelect(sheet, range, rowNums, colNums);
							},
							cellEditBefore: (range) => { // 双击单元格
								if (vm.showRowInfoByDevice) {
									return false;
								}
								luckysheetConfig.cellEditBefore(range, rowNums, colNums);

							},
							rowTitleCellRenderBefore: function(rowNum, position, ctx) {
								return false;
							},
							columnTitleCellRenderBefore: function() {
								return false;
							},
							cellMousedownBefore(cell, position) {
								vm.IsWhere = vm.indexToCell([position.r, position.c])
								luckysheet.setRangeShow(vm.IsWhere + ':' + vm.IsWhere);
								return false;
							},
							cellUpdated(r, c, oldValue, newValue, isRefresh) {
								debugger
								luckysheetConfig.cellUpdated(r, c, oldValue, newValue, isRefresh);

							}
						}
					}
					luckysheet.create(options)


					setTimeout(() => {
						/**
						 * 将FQCItems中的数据手动排序，处理过后的数据，顺序有点问题
						 */
						vm.originData.inspections.forEach(item => {
							item.FQCItems.sort(function(a, b) {
								return a.c - b.c;
							})
						});
						/** 获取根据来料数量，允许的不合格数范围
						 * FirstInspectionID  	主键ID
						 * BJNum	来料数量
						 */
						let OBJ = {
							FirstInspectionID: vm.originData.mainData[vm.InspectionConfig.keyID],
							BJNum: vm.originData.mainData.BJNum,
						}
						vm.GetAllowErrors(OBJ)
						// 根据样品检验结果，更改值
						// vm.originData.inspections.forEach((item, index) => {

						// 	vm.ChangeRowResult(item.FQCItems[0].r, index)
						// })
						// 将选中框，调整到 第一个可填位置
						if (vm.originData.inspections.length && vm.originData.inspections[0].FQCItems
							.length && vm
							.originData.inspections[0].FQCItems[0].c && vm.originData.inspections[0].FQCItems[
								0].r) {

							let IsWhere = vm.indexToCell([
								vm.originData.inspections[0].FQCItems[0].r,
								vm.originData.inspections[0].FQCItems[0].c
							])
							// 选中
							vm.IsWhere = IsWhere
							luckysheet.setRangeShow(IsWhere + ':' + IsWhere);
						}
					}, 500)

				},
				GetAllowErrors(data) { // 获取根据来料数量，允许的不合格数范围
					/**
					 * FirstInspectionID  	主键ID
					 * BJNum	来料数量
					 */
					APP.jqueryAjax('APP_selectSJJCJSL', {
						FirstInspectionID: data[vm.InspectionConfig.keyID],
						BJNum: data.BJNum
					}, function(res) {
						if (res.status == 200) {

							if (res.data.ds[0]?.status == 200) {
								vm.RejectionNum = res.data.ds[0].RejectionNum
							} else {
								// res.data.ds[0].msg
							}
						}
					})
				},
				tableData_Report_change(index) { // 报告列表切换
					let ReportData = vm.tableData_Report[index];
					Object.assign(vm.popup_ReportData, ReportData);
				},
				ViewReportInfoBtn() { // 预览报告按钮
					let index = vm.tableData_Report_radio;
					let ReportData = vm.tableData_Report[index];
					basicConfig.ViewPopupInfoByDevice(vm.DeviceInfo.NeedDevice, JSON.stringify(ReportData));

				},
				SubmitViewReportInfoBtn() { // 确认预览报告按钮
					vm.submitRowInfo();
				},
				SendReportBtn() { // 测试发送报告数据
					basicConfig.GetPopupInfoByDevice(vm.DeviceInfo.NeedDevice);
				},
				submitRowInfo() { // 报告类型弹层确认按钮事件
					basicConfig.SubmitPopupInfoByDevice(vm.DeviceInfo.NeedDevice);
				},
				submitKeyword() { // 点击输入框右侧确认按钮
					basicConfig.submitKeyword();
				},
				BlurSearch() { // 赋值输入框失焦
					if (vm.showEditWindow) {
						vm.InputFocus = 'none';

						setTimeout(() => {

							// 隐藏输入框
							vm.showEditWindow = false;
						}, 30)
					}
				},
				closeJYResult() {
					let fcColor = {
						"合格": "#07d348",
						"不合格": "#f00",
						"待检验": "#a8a8a8",
					}

					const NewData = [
						[{
							"m": vm.isJYResult, // 显示值
							"v": vm.isJYResult, // 原始值
							"ht": 1, // 水平对齐 0 居中、1 左、2右	
							"vt": 0, // 垂直对齐 0 中间、1 上、2下
							"tb": 2, // 文本换行 0 截断、1溢出、2 自动换行 
							"fc": fcColor[vm.isJYResult] || "#a8a8a8"
							// "fc": (vm.isJYResult == '合格' ? "#07d348" : "#f00")
						}]
					]
					//回写单元格
					var IsWhere = vm.indexToCell([vm.editRange[0].row[0], vm.editRange[0].column[0]])
					luckysheet.setRangeValue(NewData, {
						range: IsWhere + ':' + IsWhere
					});

					const mapData = {
						'合格': 1,
						'不合格': 0,
						'待检验': 99,
					}

					let mappedValue = mapData[vm.isJYResult];


					let findResult = vm.originData.FQCDetail.findIndex(item => {
						return item.cmax && item.cmax == vm.editRange[0].column_focus
					});

					for (let i = 0; i < vm.originData.FQCDetail.length; i++) {
						if (vm.originData.FQCDetail[i]['cmax'] && vm.originData.FQCDetail[i]['cmax'] == vm.editRange[
								0].column_focus) {
							let ReItem = vm.originData.FQCDetail[i];

							vm.originData.FQCDetail[i]['result'] = mappedValue;
							break;

						}
					}

					// vm.$set(vm.originData.FQCDetail[findResult],'result',)

					//更新主表头数据
					// var ypIndex = vm.editRange[0].row[0] - 1 - vm.headerLevel;
					// vm.originData.inspections[ypIndex].result = (vm.isJYResult == '合格' ? 1 : vm.isJYResult == '不合格' ?
					// 	2 : -1);

					// 计算合格率
					// vm.QualifiedRate = BackRercentageData(vm.originData.inspections, 'result', 1)


					if (vm.isJYResult == "合格") {
						luckysheet.setDataVerification({
							type: 'checkbox',
							type2: null,
							value1: '合格',
							value2: '不合格',
							checked: true
						});
					} else if (vm.isJYResult == "不合格") {
						luckysheet.setDataVerification({
							type: 'checkbox',
							type2: null,
							value1: '合格',
							value2: '不合格',
							checked: false
						});
					} else {
						luckysheet.setDataVerification({
							type: 'checkbox',
							type2: null,
							value1: '合格',
							value2: '待检验',
							checked: false
						});
					}
					luckysheet.setRangeShow('A1:A1', {
						show: false
					});
				},
				selectCellResult(flash) { // 检验标准实测值取值弹层
					vm.showSelectCellResult = false;
					vm.isSelectCellResult = flash;
					basicConfig.submitKeyword(1);
				},
				closeSelectCellResult() {
					vm.showEditWindow = false;
					vm.allowToNext = false;
				},
				onClickLeft() {
					vant.Dialog.confirm({
						title: '提示',
						message: '是否确认退出？',
					}).then(() => {
						vm.GoBack()
					}).catch(() => {

					});
				}
			}
		})

		// 监听屏幕旋转
		window.addEventListener("orientationchange", function() {

			if (Math.abs(window.orientation) === 90) {
				// console.log('这是竖屏')
			}
			if (Math.abs(window.orientation) === 0) {
				// console.log('这是横屏')
			}
		}, false);


		/** 根据选中的单元格位置，获取单元格的信息 用于'originData.inspections'
		 * @param arr  搜寻的原数组， this.originData.inspections
		 * @param data 选中的坐标位置，如 {r:0,c:0}
		 */
		function GetChoiceCellData1(arr, data) {
			var that = this
			for (var i = 0; i < arr.length; i++) {
				for (var j = 0; j < arr[i].FQCItems.length; j++) {

					if (arr[i].FQCItems[j].r == data.r &&
						arr[i].FQCItems[j].c == data.c) {

						return arr[i].FQCItems[j]
					}
				}
			}
		}

		/**
		 * 根据选中的单元格位置，获取单元格的信息 用于'originData.inspections'
		 * @param {Array} arr  搜寻的原数组， this.originData.inspections
		 * @param {Object} data 选中的坐标位置，如 {r:0, c:0}
		 * @return {Object|undefined} 找到的单元格对象，如果没有找到则返回 undefined
		 */
		function GetChoiceCellData(arr, data) {
			var rowCount = arr.length;
			var foundItem = undefined;

			// 使用标志变量来跟踪是否找到匹配项，以便可以早期退出
			var found = false;

			for (var i = 0; i < rowCount && !found; i++) {
				var fqcItems = arr[i].FQCItems;
				var itemCount = fqcItems.length;

				for (var j = 0; j < itemCount && !found; j++) {
					if (fqcItems[j].r === data.r && fqcItems[j].c === data.c) {
						foundItem = fqcItems[j];
						found = true; // 设置标志为 true，以便外层循环可以早期退出
					}
				}
			}

			return foundItem;
		}

		/**
		 * 求百分比函数
		 * 求该字段在数组中所占百分比
		 * @param arr 		对象数组
		 * @param attribute 字段名称
		 * @param value 	比较的值
		 * @return {string} 返回一个字符串（'50%'）
		 */
		function BackRercentageData(arr, attribute, value) {

			let MeetNums = arr.filter(item => {
				/* 当Fresult是无值的情况下，默认为1 */
				let data = item[attribute];
				if (APP.isEmpty(item[attribute])) {
					data = 1;
				}
				return data == value
			}).length

			let num = parseFloat(MeetNums);
			let total = parseFloat(arr.length);

			if (isNaN(num) || isNaN(total)) {
				return "-";
			}
			return total <= 0 ? "0%" : Math.round((num / total) * 10000) / 100.0 + "%";
		}

		/**
		 * 求百分比
		 * @param  num 		当前数
		 * @param  total 	总数
		 * @return {string} 返回一个字符串（'50%'）
		 */
		function getPercent(num, total) {
			num = parseFloat(num);
			total = parseFloat(total);
			if (isNaN(num) || isNaN(total)) {
				return "-";
			}
			return total <= 0 ? "0%" : Math.round((num / total) * 10000) / 100.0 + "%";
		}

		/** 求对象数组中某一属性最大值
		 * @param arr 对象数组
		 * @param key 对比的属性
		 */
		function countMax(arr, key) {
			return Math.max.apply(Math, arr.map(item => {
				return item[key]
			}))
		}
	</script>

</html>